﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Bson;
using JXT.PrimaryKey.Batman.Domain.Quotation.Models;
using JXT.PrimaryKey.Batman.Domain.Quotation.Repositories;

namespace JXT.PrimaryKey.Batman.Domain.Repositories.Quotation
{
    public class FileTimeSharingQuoteRepository : ITimeSharingQuoteRepository
    {
        private TimeSharingQuoteStoreEngine _storeEngine;

        public FileTimeSharingQuoteRepository(string documentRoot)
        {
            _storeEngine = new TimeSharingQuoteStoreEngine(documentRoot);
            _storeEngine.InitDocumentRoot();
        }

        public void Add(TimeSharingQuote entity)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            _storeEngine.Save(ClassToStruct(entity));
        }

        public void Delete(DateTime endTime)
        {
            
        }

        public TimeSharingQuote GetSingle(string code, MarketType type = MarketType.Unknown)
        {
            if (type == MarketType.Unknown)
                throw new ArgumentException("type can not be unknown.");
            var find = _storeEngine.ReadLast((byte)type, code);
            //var find = _storeEngine.MemoryMappedReadLast((byte)type, code);
            return StructToClass(find);
        }

        public IEnumerable<TimeSharingQuote> GetList(string code, MarketType type = MarketType.Unknown, DateTime? startTime = null, DateTime? endTime = null)
        {
            if (type == MarketType.Unknown)
                throw new ArgumentException("type can not be unknown.");
            long startTimeLong = startTime == null ? -1 : startTime.Value.Ticks;
            long endTimeLong = endTime == null ? -1 : endTime.Value.Ticks;
            var list = _storeEngine.Read((byte)type, code, startTimeLong, SearchType.More, endTimeLong, SearchType.Less);
            //var list = _storeEngine.MemoryMappedRead((byte)type, code, startTimeLong, SearchType.More, endTimeLong, SearchType.Less);
            return list.Select(e => StructToClass(e)).ToList();
        }

        private static TimeSharingQuoteStruct ClassToStruct(TimeSharingQuote data)
        {
            return new TimeSharingQuoteStruct()
            {
                AveragePrice = data.AveragePrice,
                ChangePrice = data.ChangePrice,
                ChangeRate = data.ChangeRate,
                ClosePrice = data.ClosePrice,
                Code = data.Code,
                HighestPrice = data.HighestPrice,
                LastPrice = data.LastPrice,
                LowestPrice = data.LowestPrice,
                MarketType = (byte)data.MarketType,
                OpenPrice = data.OpenPrice,
                TradingNum = data.TradingNum,
                TradingVolume = data.TradingVolume,
                Turnover = data.Turnover,
                UpdateTime = data.UpdateTime.Ticks
            };
        }

        private static TimeSharingQuote StructToClass(TimeSharingQuoteStruct data)
        {
            return new TimeSharingQuote()
            {
                AveragePrice = data.AveragePrice,
                ChangePrice = data.ChangePrice,
                ChangeRate = data.ChangeRate,
                ClosePrice = data.ClosePrice,
                Code = data.Code,
                HighestPrice = data.HighestPrice,
                LastPrice = data.LastPrice,
                LowestPrice = data.LowestPrice,
                MarketType = (MarketType)data.MarketType,
                OpenPrice = data.OpenPrice,
                TradingNum = data.TradingNum,
                TradingVolume = data.TradingVolume,
                Turnover = data.Turnover,
                UpdateTime = DateTime.FromBinary(data.UpdateTime)
            };
        }

        #region IRepository<TimeSharingQuote> Members

        public RepositoryContext Context
        {
            get { return null; }
        }

        #endregion
    }
}
